﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using Microsoft.Win32;

namespace XDFileDialog.Help
{
    /// <summary>
    /// 目录帮助方法
    /// </summary>
    internal static class CatalogHelp
    {
        /// <summary>
        /// 文件类型集合
        /// </summary>
        public static List<CatalogType> CatalogType = new List<CatalogType>();

        /// <summary>
        /// 获取文件夹内的子文件夹名称
        /// </summary>
        public static string[] GetDirectories(string path)
        {
            return System.IO.Directory.GetDirectories(path).Select(c => c.Substring(c.LastIndexOf('\\') + 1)).ToArray();
        }
        /// <summary>
        /// 获取文件夹内的文件名称
        /// </summary>
        public static string[] GetFiles(string path,string exp)
        {
            return System.IO.Directory.GetFiles(path, exp).Select(c => c.Substring(c.LastIndexOf('\\') + 1)).ToArray();
        }
        /// <summary>
        /// 获取文件夹内的文件集合
        /// </summary>
        public static List<Catalog> GetFilesCatalog(string path,string exp)
        {
            List<Catalog> list = new List<Catalog>();

            string[] pathName = GetFiles(path,exp);
            pathName = pathName.Where(c => c != "$RECYCLE.BIN").ToArray();
            List<System.Threading.Tasks.Task> taskList = new List<System.Threading.Tasks.Task>();
            foreach (var item in pathName)
            {
                System.Threading.Tasks.Task task = new System.Threading.Tasks.Task(delegate(object o)
                 {
                     string catalogPath = string.Concat(path, "\\", o.ToString());
                     catalogPath = catalogPath.Replace("\\\\", "\\");
                     Catalog model = new Catalog();
                     model.Name = o.ToString();
                     model.Type = GetCatalogType(item);
                     model.Icon = SystemIconHelp.GetFileIcon(catalogPath, false).ToBitmap();
                     FileInfo fileInfo = new FileInfo(catalogPath);
                     model.LastUpdateTime = fileInfo.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss");
                     model.Size = GetLenght(fileInfo.Length, "B");
                     lock (list)
                     {
                         list.Add(model);
                     }

                 }, item);
                task.Start();
                taskList.Add(task);
            }

            foreach (var item in taskList)
            {
                item.Wait();
            }
            return list;
        }
        /// <summary>
        /// 获取文件夹内的目录集合
        /// </summary>
        public static List<Catalog> GetDirectorCatalog(string path)
        {
            List<Catalog> list = new List<Catalog>();
            Icon icon = SystemIconHelp.GetFolderIcon(false);
            string[] pathName = GetDirectories(path);
            foreach (var item in pathName)
            {
                try
                {
                    if (item.Contains("$RECYCLE.BIN"))
                    {
                        continue;
                    }
                    string catalogPath = string.Concat(path, "\\", item);

                    Catalog model = new Catalog();
                    model.Name = item;
                    model.LastUpdateTime = Directory.GetLastWriteTime(catalogPath).ToString("yyyy-MM-dd HH:mm:ss");
                    model.Type = "文件夹";
                    model.Icon = icon.ToBitmap();
                    list.Add(model);
                }
                catch
                {
                }

            }
            return list;
        }
        /// <summary>
        /// 获取文件夹内所有集合
        /// </summary>
        public static List<Catalog> GetCatalog(string path,string exp)
        {
            path = path.Replace("\\\\", "\\");
            List<Catalog> list = GetDirectorCatalog(path);

            list.AddRange(GetFilesCatalog(path,exp));
            return list;
        }

        /// <summary>
        /// 返回文件的类型
        /// </summary>
        public static string GetCatalogType(string str)
        {
            if (str.IndexOf('.') <= 0)
            {
                return "文件";
            }
            string ext = str.Substring(str.LastIndexOf('.'));  //".mp3"; 
            try
            {
                List<CatalogType> list = CatalogType.Where(c => c.exp == ext).ToList();
                if (list.Count == 0)
                {
                    string desc = (string)Registry.ClassesRoot.OpenSubKey(ext).GetValue(null);
                    string type = (string)Registry.ClassesRoot.OpenSubKey(desc).GetValue(null);
                    CatalogType.Add(new CatalogType()
                    {
                        exp = ext,
                        Name = desc,
                        Type = type
                    });
                    return type;
                }
                else
                {
                    return list[0].Type;
                }

            }
            catch (Exception ex)
            {
                CatalogType.Add(new CatalogType()
                {
                    exp = ext,
                    Type = ext.ToUpper() + "文件"
                });
                return ext.ToUpper() + "文件";
            }
        }
        public static string GetLenght(decimal lenght, string str)
        {
            if (lenght > 1024)
            {
                decimal de = lenght / 1024;
                switch (str)
                {
                    case "B":
                        str = "KB";
                        break;
                    case "KB":
                        str = "MB";
                        break;
                    case "MB":
                        str = "GB";
                        break;
                    case "GB":
                        str = "TB";
                        break;
                    case "TB":
                        str = "PB";
                        break;
                    case "PB":
                        str = "EB";
                        break;
                }
                return GetLenght(de, str);
            }
            else
            {
                return lenght.ToString("0.00") + str;
            }
        }

    }
    /// <summary>
    /// 目录及文件
    /// </summary>
    public class Catalog
    {
        /// <summary>
        /// 文件名称
        /// </summary>
        public string Name { set; get; }
        /// <summary>
        /// 最后修改时间
        /// </summary>
        public string LastUpdateTime { set; get; }
        /// <summary>
        /// 类型
        /// </summary>
        public string Type { set; get; }
        /// <summary>
        /// 大小
        /// </summary>
        public string Size { set; get; }
        /// <summary>
        /// 图标
        /// </summary>
        public Bitmap Icon { set; get; }
    }

    public class CatalogType
    {
        /// <summary>
        /// 后缀
        /// </summary>
        public string exp { set; get; }
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { set; get; }
        /// <summary>
        /// 类型
        /// </summary>
        public string Type { set; get; }
    }
}
